home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / tiffs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-07  |  35.4 KB  |  1,272 lines

  1.  
  2.    /*************************** 
  3.    * 
  4.    *   tiffs.c 
  5.    *   COMPOSITE FILE COMPRISING: 
  6.    *   rtiff.c 
  7.    *   wtiff.c 
  8.    *   tiff.c 
  9.    * 
  10.    ***************************\ 
  11.  
  12.  
  13.  
  14.        /*********************************************
  15.        *
  16.        *  file d:\cips\rtiff.c
  17.        *
  18.        *  Functions: This file contains
  19.        *          read_tiff_image
  20.        *          read_line
  21.        *          seek_to_first_line
  22.        *          seek_to_end_of_line
  23.        *
  24.        *  Purpose:
  25.        *  These functions read a TIFF image and insert
  26.        *  the data into a ROWSxCOLS array of short.
  27.        *
  28.        *       NOTE: The fseek constants are
  29.        *             0=SEEK_SET = beginning of file
  30.        *             1=SEEK_CUR = current offset
  31.        *             2=SEEK_END = end of file
  32.        *
  33.        *  External Calls:
  34.        *  tiff.c - read_tiff_header
  35.        *
  36.        *  Modifications:
  37.        *       25 June 1990 - created
  38.        *       27 March 1993 - use fopen, fread, fseek
  39.        *           instead of the earlier open, read,
  40.        *           seek, etc.
  41.        *
  42.        **********************************************/
  43.  
  44. #include "cips.h"
  45.  
  46.  
  47.  
  48.  
  49.  
  50. read_tiff_image(image_file_name, array, il, ie, ll, le)
  51.       char   image_file_name[];
  52.       int    il, ie, ll, le;
  53.       short   array[ROWS][COLS];
  54. {
  55.    char  buffer[COLS],
  56.          rep[80];
  57.    int   bytes_read,
  58.          closed,
  59.          position,
  60.          i;
  61.    FILE  *image_file;
  62.    float a;
  63.    long  line_length, offset;
  64.  
  65.    struct tiff_header_struct image_header;
  66.  
  67.    read_tiff_header(image_file_name, &image_header);
  68.  
  69.       /***********************************************
  70.       *
  71.       *   Procedure:
  72.       *   Seek to the strip offset where the data begins.
  73.       *   Seek to the first line you want.
  74.       *   Loop over the lines you want to read:
  75.       *      Seek to the first element of the line.
  76.       *      Read the line.
  77.       *      Seek to the end of the data in that line.
  78.       *
  79.       ************************************************/
  80.  
  81.    image_file = fopen(image_file_name, "rb");
  82.    if(image_file != NULL){
  83.       position = fseek(image_file, 
  84.                        image_header.strip_offset, 
  85.                        SEEK_SET);
  86.       position = seek_to_first_line(image_file, 
  87.                                     &image_header, il);
  88.  
  89.       for(i=0; i<(ll-il); i++){
  90.          offset       = (ie-1)/
  91.                         (8/image_header.bits_per_pixel);
  92.          position     = fseek(image_file, offset, 
  93.                               SEEK_CUR);
  94.          bytes_read   = read_line(image_file, array, 
  95.                                   i, &image_header, 
  96.                                   ie, le);
  97.          position     = seek_to_end_of_line(image_file, 
  98.                                  le, &image_header);
  99.          position     = fseek(image_file, 1, 
  100.                               SEEK_CUR); 
  101.       }  /* ends loop over i  */
  102.  
  103.       closed = fclose(image_file);
  104.    }  /* ends if file opened ok */
  105.    else{
  106.       printf("\nRTIFF.C> ERROR - cannot open "
  107.              "tiff file");
  108.    }
  109.  
  110. }  /*  ends read_tiff_image */
  111.  
  112.  
  113.  
  114.  
  115.        /**********************************************
  116.        *
  117.        *   read_line(...
  118.        *
  119.        *   This function reads bytes from the TIFF 
  120.        *   file into a buffer, extracts the numbers 
  121.        *   from that buffer, and puts them into a 
  122.        *   ROWSxCOLS array of shorts. The process 
  123.        *   depends on the number of bits per pixel used 
  124.        *   in the file (4 or 8).
  125.        *
  126.        **********************************************/
  127.  
  128. read_line(image_file, array, line_number, 
  129.           image_header, ie, le)
  130.    FILE   *image_file;
  131.    int    ie, le, line_number;
  132.    short  array[ROWS][COLS];
  133.    struct tiff_header_struct *image_header;
  134. {
  135.    char  buffer[COLS], first, second;
  136.    float a, b;
  137.    int bytes_read, i;
  138.    unsigned int bytes_to_read;
  139.    union short_char_union scu;
  140.  
  141.    for(i=0; i<COLS; i++)
  142.       buffer[i] = '\0';
  143.  
  144.         /********************************************
  145.         *
  146.         *   Use the number of bits per pixel to 
  147.         *   calculate how many bytes to read.
  148.         *
  149.         ********************************************/
  150.  
  151.    bytes_to_read = (le-ie)/
  152.                    (8/image_header->bits_per_pixel);
  153.    bytes_read    = fread(buffer, 1, bytes_to_read, 
  154.                          image_file);
  155.  
  156.    for(i=0; i<bytes_read; i++){
  157.  
  158.         /*********************************************
  159.         *
  160.         *   Use unions defined in cips.h to stuff bytes
  161.         *   into shorts.
  162.         *
  163.         **********************************************/
  164.  
  165.       if(image_header->bits_per_pixel == 8){
  166.        scu.s_num          = 0;
  167.        scu.s_alpha[0]        = buffer[i];
  168.        array[line_number][i] = scu.s_num;
  169.       }  /* ends if bits_per_pixel == 8 */
  170.  
  171.       if(image_header->bits_per_pixel == 4){
  172.  
  173.        scu.s_num             = 0;
  174.        second                = buffer[i] & 0X000F;
  175.        scu.s_alpha[0]        = second;
  176.        array[line_number][i*2+1] = scu.s_num;
  177.  
  178.        scu.s_num             = 0;
  179.        first                 = buffer[i] >> 4;
  180.        first                 = first & 0x000F;
  181.        scu.s_alpha[0]        = first;
  182.        array[line_number][i*2] = scu.s_num;
  183.  
  184.       }  /* ends if bits_per_pixel == 4 */
  185.  
  186.    }  /*  ends loop over i  */
  187.  
  188.    return(bytes_read);
  189.  
  190. }  /* ends read_line  */
  191.  
  192.  
  193.  
  194.  
  195.  
  196.        /*********************************************
  197.        *
  198.        *   seek_to_first_line(...
  199.        *
  200.        **********************************************/
  201.  
  202. seek_to_first_line(image_file, image_header, il)
  203.    FILE   *image_file;
  204.    int    il;
  205.    struct tiff_header_struct *image_header;
  206. {
  207.    long offset;
  208.    int  position;
  209.  
  210.    offset   = (il-1)*image_header->image_width/
  211.              (8/image_header->bits_per_pixel);
  212.       /* seek from current position */
  213.    position = fseek(image_file, offset, SEEK_CUR);
  214.    return(position);
  215. }  /* ends seek_to_first_line */
  216.  
  217.  
  218.  
  219.  
  220.  
  221.        /**********************************************
  222.        *
  223.        *   seek_to_end_of_line(...
  224.        *
  225.        ***********************************************/
  226.  
  227. seek_to_end_of_line(image_file, le, image_header)
  228.    FILE   *image_file;
  229.    int    le;
  230.    struct tiff_header_struct *image_header;
  231. {
  232.    long  offset;
  233.    int   position;
  234.  
  235.    offset   = (image_header->image_width-le)/
  236.              (8/image_header->bits_per_pixel);
  237.    position = fseek(image_file, offset, SEEK_CUR);
  238.    return(position);
  239. }  /* ends seek_to_end_of_line         */
  240.  
  241.        /**********************************************
  242.        *
  243.        *  file d:\cips\wtiff.c
  244.        *
  245.        *  Functions: This file contains
  246.        *      create_file_if_needed
  247.        *      create_allocate_tiff_file
  248.        *      write_array_into_tiff_image
  249.        *      write_line
  250.        *      insert_short_into_buffer
  251.        *      insert_long_into_buffer
  252.        *      round_off_image_size
  253.        *      does_not_exist
  254.        *
  255.        *  Purpose:
  256.        *     These functions create TIFF image files 
  257.        *     on disk and insert a ROWSxCOLS array
  258.        *     into a tiff image already stored on disk.
  259.        *
  260.        *  External Calls:
  261.        *     rtiff.c - seek_to_first_line
  262.        *               seek_to_end_of_line
  263.        *     tiff.c - read_tiff_header
  264.        *
  265.        *  Modifications:
  266.        *     29 January 1991 - created
  267.        *     28 March 1993 - replaced open, lseek
  268.        *         etc. with fopen, fseek, etc.
  269.        *     10 May 1993 - added a number of tags
  270.        *         to make the TIFF files I create
  271.        *         TIFF 6.0 Gray Scale image compliant.
  272.        *
  273.        *********************************************/
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.        /**********************************************
  281.        *
  282.        *   create_file_if_needed(...
  283.        *
  284.        *   This function creates a file on disk
  285.        *   if it does not exist.  The out file is
  286.        *   patterned after the in file.
  287.        *
  288.        ***********************************************/
  289.  
  290. create_file_if_needed(in_name, out_name, out_image)
  291.    char in_name[], out_name[];
  292.    short out_image[ROWS][COLS];
  293. {
  294.    int    length, width;
  295.    struct tiff_header_struct image_header;
  296.  
  297.    if(does_not_exist(out_name)){
  298.       printf("\n\n output file does not exist %s",
  299.                out_name);
  300.       read_tiff_header(in_name, &image_header);
  301.       round_off_image_size(&image_header,
  302.                            &length, &width);
  303.       image_header.image_length = length*ROWS;
  304.       image_header.image_width  = width*COLS;
  305.       create_allocate_tiff_file(out_name, &image_header,
  306.                                 out_image);
  307.    }  /* ends if does_not_exist */
  308. }  /* ends create_file_if_needed */
  309.  
  310.  
  311.  
  312.  
  313.  
  314.    /**********************************************
  315.    *
  316.    *   create_alllocate_tiff_file(...
  317.    *
  318.    *   This function creates a file on disk that will be
  319.    *   large enough to hold a tiff image.  The input
  320.    *   tiff_header_struct describes the desired tiff file.
  321.    *   This function writes the tiff header and then
  322.    *   writes a blank image array out to disk the proper
  323.    *   number of times.  This has the effect of allocating
  324.    *   the correct number of bytes on the disk.
  325.    *
  326.    *   There will be 18 entries in the IFD.
  327.    *   The image data will begin at byte 296.
  328.    *   I will use LSB first data.
  329.    *   I will have one strip for the entire image.
  330.    *   Black is zero.
  331.    *   The component values for the image are CHUNKY
  332.    *      (Planer configuration = 1).
  333.    *
  334.    ***************************************************/
  335.  
  336.  
  337. create_allocate_tiff_file(file_name, 
  338.                           image_header, image)
  339.    char   file_name[];
  340.    short  image[ROWS][COLS];
  341.    struct tiff_header_struct *image_header;
  342. {
  343.    char  buffer[12], long_buffer[50];
  344.    FILE  *image_file;
  345.    int   bytes_written,
  346.          i,
  347.          j,
  348.          l,
  349.          w;
  350.  
  351.    long  k;
  352.  
  353.  
  354.  
  355.       /***************************************
  356.       *
  357.       *   Create the image file in binary mode
  358.       *   for both reading and writing.
  359.       *
  360.       ****************************************/
  361.  
  362.    image_file = fopen(file_name, "wb");
  363.  
  364.       /***************************************
  365.       *
  366.       *   Write out the first 8 bytes of the
  367.       *   header.  The meaning of the
  368.       *   bytes (HEX) is:
  369.       *      0-1 = 49 49 - LSB first
  370.       *      2-3 = 2A 00 - version #
  371.       *      4-7 = 08 00 00 00 - go to offset
  372.       *           8 for the first
  373.       *           Image File
  374.       *           Directory
  375.       *
  376.       ****************************************/
  377.  
  378.    buffer[0] = 0x49;
  379.    buffer[1] = 0x49;
  380.    buffer[2] = 0x2A;
  381.    buffer[3] = 0x00;
  382.    buffer[4] = 0x08;
  383.    buffer[5] = 0x00;
  384.    buffer[6] = 0x00;
  385.    buffer[7] = 0x00;
  386.  
  387.    bytes_written = fwrite(buffer, 1, 8, image_file);
  388.  
  389.    printf("\n wrote %d bytes", bytes_written);
  390.  
  391.       /***************************************
  392.       *
  393.       *   Write out the first 2 bytes of the
  394.       *   Image File Directory.  These tell
  395.       *   the number of entries in the IFD.
  396.       *
  397.       ****************************************/
  398.  
  399.    buffer[0] = 0x12;
  400.    buffer[1] = 0x00;
  401.    bytes_written = fwrite(buffer, 1, 2, image_file);
  402.  
  403.    printf("\n wrote %d bytes", bytes_written);
  404.  
  405.       /***************************************
  406.       *
  407.       *   Write out the entries into the
  408.       *   Image File Directory.
  409.       *
  410.       ****************************************/
  411.  
  412.  
  413.       /* New Subfile Type */
  414.    buffer[0]  = 0xFE;
  415.    buffer[1]  = 0x00;
  416.    buffer[2]  = 0x03;
  417.    buffer[3]  = 0x00;
  418.    buffer[4]  = 0x01;
  419.    buffer[5]  = 0x00;
  420.    buffer[6]  = 0x00;
  421.    buffer[7]  = 0x00;
  422.    buffer[8]  = 0x00;
  423.    buffer[9]  = 0x00;
  424.    buffer[10] = 0x00;
  425.    buffer[11] = 0x00;
  426.    bytes_written = fwrite(buffer, 1, 12, image_file);
  427.    printf("\n wrote %d bytes", bytes_written);
  428.  
  429.  
  430.       /* Subfile Type */
  431.    buffer[0]  = 0xFF;
  432.    buffer[1]  = 0x00;
  433.    buffer[2]  = 0x03;
  434.    buffer[3]  = 0x00;
  435.    buffer[4]  = 0x01;
  436.    buffer[5]  = 0x00;
  437.    buffer[6]  = 0x00;
  438.    buffer[7]  = 0x00;
  439.    buffer[8]  = 0x01;
  440.    buffer[9]  = 0x00;
  441.    buffer[10] = 0x00;
  442.    buffer[11] = 0x00;
  443.    bytes_written = fwrite(buffer, 1, 12, image_file);
  444.    printf("\n wrote %d bytes", bytes_written);
  445.  
  446.  
  447.       /* Image Width */
  448.    insert_short_into_buffer(buffer, 0, 256);
  449.    insert_short_into_buffer(buffer, 2, 3);
  450.    insert_short_into_buffer(buffer, 4, 1);
  451.    insert_short_into_buffer(buffer, 8, 
  452.                      image_header->image_width);
  453.    bytes_written = fwrite(buffer, 1, 12, image_file);
  454.    printf("\n wrote %d bytes", bytes_written);
  455.  
  456.  
  457.       /* Image Length */
  458.    insert_short_into_buffer(buffer, 0, 257);
  459.    insert_short_into_buffer(buffer, 2, 3);
  460.    insert_short_into_buffer(buffer, 4, 1);
  461.    insert_short_into_buffer(buffer, 8, 
  462.                      image_header->image_length);
  463.    bytes_written = fwrite(buffer, 1, 12, image_file);
  464.    printf("\n wrote %d bytes", bytes_written);
  465.  
  466.  
  467.       /* Bits Per Sample */
  468.    insert_short_into_buffer(buffer, 0, 258);
  469.    insert_short_into_buffer(buffer, 2, 3);
  470.    insert_short_into_buffer(buffer, 4, 1);
  471.    insert_short_into_buffer(buffer, 8, 
  472.                      image_header->bits_per_pixel);
  473.    bytes_written = fwrite(buffer, 1, 12, image_file);
  474.    printf("\n wrote %d bytes", bytes_written);
  475.  
  476.  
  477.       /* Compression - None */
  478.    insert_short_into_buffer(buffer, 0, 259);
  479.    insert_short_into_buffer(buffer, 2, 3);
  480.    insert_short_into_buffer(buffer, 4, 1);
  481.    insert_short_into_buffer(buffer, 8, 1);
  482.    bytes_written = fwrite(buffer, 1, 12, image_file);
  483.    printf("\n wrote %d bytes", bytes_written);
  484.  
  485.  
  486.       /* Photometric Interpretation */
  487.       /* set to 1 because BLACK is ZERO */
  488.    insert_short_into_buffer(buffer, 0, 262);
  489.    insert_short_into_buffer(buffer, 2, 3);
  490.    insert_short_into_buffer(buffer, 4, 1);
  491.    insert_short_into_buffer(buffer, 8, 1);
  492.    bytes_written = fwrite(buffer, 1, 12, image_file);
  493.    printf("\n wrote %d bytes", bytes_written);
  494.  
  495.  
  496.       /* Strip Offset */
  497.       /* start after software name at 296 */
  498.    insert_short_into_buffer(buffer, 0, 273);
  499.    insert_short_into_buffer(buffer, 2, 3);
  500.    insert_short_into_buffer(buffer, 4, 1);
  501.    insert_short_into_buffer(buffer, 8, 296);
  502.    bytes_written = fwrite(buffer, 1, 12, image_file);
  503.    printf("\n wrote %d bytes", bytes_written);
  504.  
  505.  
  506.       /* Samples per Pixel */
  507.    insert_short_into_buffer(buffer, 0, 277);
  508.    insert_short_into_buffer(buffer, 2, 3);
  509.    insert_short_into_buffer(buffer, 4, 1);
  510.    insert_short_into_buffer(buffer, 8, 1);
  511.    bytes_written = fwrite(buffer, 1, 12, image_file);
  512.    printf("\n wrote %d bytes", bytes_written);
  513.  
  514.  
  515.       /* clear buffer */
  516.    for(i=0; i<12; i++) buffer[i] = 0x00;
  517.  
  518.       /* Rows Per Strip 1 strip for the entire image */
  519.       /* use 2E32 - 1, which is max */
  520.    insert_short_into_buffer(buffer, 0, 278);
  521.    insert_short_into_buffer(buffer, 2, 4);
  522.    insert_short_into_buffer(buffer, 4, 1);
  523.    insert_long_into_buffer(buffer, 8, 4294967295);
  524.    bytes_written = fwrite(buffer, 1, 12, image_file);
  525.    printf("\n wrote %d bytes", bytes_written);
  526.  
  527.  
  528.       /* Strip Byte Counts */
  529.       /* this = image width times length */
  530.    insert_short_into_buffer(buffer, 0, 279);
  531.    insert_short_into_buffer(buffer, 2, 4);
  532.    insert_short_into_buffer(buffer, 4, 1);
  533.    insert_long_into_buffer(buffer, 8, 
  534.     (long)(image_header->image_length *
  535.            image_header->image_width));
  536.    bytes_written = fwrite(buffer, 1, 12, image_file);
  537.    printf("\n wrote %d bytes", bytes_written);
  538.  
  539.  
  540.       /* Min Sample Value */
  541.    insert_short_into_buffer(buffer, 0, 280);
  542.    insert_short_into_buffer(buffer, 2, 3);
  543.    insert_short_into_buffer(buffer, 4, 1);
  544.    insert_short_into_buffer(buffer, 8, 0);
  545.    bytes_written = fwrite(buffer, 1, 12, image_file);
  546.    printf("\n wrote %d bytes", bytes_written);
  547.  
  548.  
  549.       /* Max Sample Value */
  550.    insert_short_into_buffer(buffer, 0, 281);
  551.    insert_short_into_buffer(buffer, 2, 3);
  552.    insert_short_into_buffer(buffer, 4, 1);
  553.    if(image_header->bits_per_pixel == 8)
  554.       insert_short_into_buffer(buffer, 8, 255);
  555.    else
  556.       insert_short_into_buffer(buffer, 8, 15);
  557.    bytes_written = fwrite(buffer, 1, 12, image_file);
  558.    printf("\n wrote %d bytes", bytes_written);
  559.  
  560.  
  561.       /* X Resolution */
  562.       /* Store the 8 bytes for this value
  563.          starting at 230 */
  564.    insert_short_into_buffer(buffer, 0, 282);
  565.    insert_short_into_buffer(buffer, 2, 5);
  566.    insert_short_into_buffer(buffer, 4, 1);
  567.    insert_short_into_buffer(buffer, 8, 230);
  568.    bytes_written = fwrite(buffer, 1, 12, image_file);
  569.    printf("\n wrote %d bytes", bytes_written);
  570.  
  571.  
  572.       /* Y Resolution */
  573.       /* Store the 8 bytes for this value
  574.          starting at 238 */
  575.    insert_short_into_buffer(buffer, 0, 283);
  576.    insert_short_into_buffer(buffer, 2, 5);
  577.    insert_short_into_buffer(buffer, 4, 1);
  578.    insert_short_into_buffer(buffer, 8, 238);
  579.    bytes_written = fwrite(buffer, 1, 12, image_file);
  580.    printf("\n wrote %d bytes", bytes_written);
  581.  
  582.  
  583.  
  584.       /* clear buffer */
  585.    for(i=0; i<12; i++) buffer[i] = 0x00;
  586.  
  587.       /* Planer Configuration */
  588.       /* chunky */
  589.    insert_short_into_buffer(buffer, 0, 284);
  590.    insert_short_into_buffer(buffer, 2, 3);
  591.    insert_short_into_buffer(buffer, 4, 1);
  592.    insert_short_into_buffer(buffer, 8, 1);
  593.    bytes_written = fwrite(buffer, 1, 12, image_file);
  594.    printf("\n wrote %d bytes", bytes_written);
  595.  
  596.  
  597.       /* Resolution Unit */
  598.       /* inches */
  599.    insert_short_into_buffer(buffer, 0, 296);
  600.    insert_short_into_buffer(buffer, 2, 3);
  601.    insert_short_into_buffer(buffer, 4, 1);
  602.    insert_short_into_buffer(buffer, 8, 2);
  603.    bytes_written = fwrite(buffer, 1, 12, image_file);
  604.    printf("\n wrote %d bytes", bytes_written);
  605.  
  606.  
  607.       /* Software */
  608.       /* Put this a 246, 50 bytes */
  609.    insert_short_into_buffer(buffer, 0, 305);
  610.    insert_short_into_buffer(buffer, 2, 2);
  611.    insert_short_into_buffer(buffer, 4, 50);
  612.    insert_short_into_buffer(buffer, 8, 246);
  613.    bytes_written = fwrite(buffer, 1, 12, image_file);
  614.    printf("\n wrote %d bytes", bytes_written);
  615.  
  616.  
  617.       /* Offset to next IFD (0 means no more IFD's) */
  618.    for(i=0; i<12; i++) buffer[i] = 0x00;
  619.    bytes_written = fwrite(buffer, 1, 4, image_file);
  620.    printf("\n wrote %d bytes", bytes_written);
  621.  
  622.  
  623.       /* clear buffer */
  624.    for(i=0; i<12; i++) buffer[i] = 0x00;
  625.  
  626.       /* Now store the X Resolution
  627.          first long is numerator
  628.          second long is denominator */
  629.    insert_long_into_buffer(buffer, 0, 300L);
  630.    insert_long_into_buffer(buffer, 4, 1L);
  631.    bytes_written = fwrite(buffer, 1, 8, image_file);
  632.    printf("\n wrote %d bytes", bytes_written);
  633.  
  634.  
  635.       /* Now store the Y Resolution
  636.          first long is numerator
  637.          second long is denominator */
  638.    insert_long_into_buffer(buffer, 0, 300L);
  639.    insert_long_into_buffer(buffer, 4, 1L);
  640.    bytes_written = fwrite(buffer, 1, 8, image_file);
  641.    printf("\n wrote %d bytes", bytes_written);
  642.  
  643.  
  644.       /* Now store the software tag */
  645.    for(i=0; i<50; i++) long_buffer[i] = '\0';
  646.    strcpy(long_buffer,
  647.    "Dwayne Phillips C Image Processing System 1993");
  648.    long_buffer[46] = '\0';
  649.    long_buffer[47] = '\0';
  650.    long_buffer[48] = '\0';
  651.    long_buffer[49] = '\0';
  652.    bytes_written = fwrite(long_buffer, 1, 50, 
  653.                           image_file);
  654.    printf("\n wrote %d bytes", bytes_written);
  655.    printf("\n%s", long_buffer);
  656.  
  657.  
  658.  
  659.       /***************************************
  660.       *
  661.       *   Now write the image data.
  662.       *
  663.       ****************************************/
  664.  
  665.    printf("\n length is %ld", 
  666.           image_header->image_length);
  667.    printf("\n width is %ld", 
  668.           image_header->image_width);
  669.  
  670.    round_off_image_size(image_header, &l, &w);
  671.    k = l * w;
  672.  
  673.    if(image_header->bits_per_pixel == 8)
  674.       k = k/2;
  675.    else
  676.       k = k/4;
  677.    k++;
  678.  
  679.    for(i=0; i<ROWS; i++)
  680.       for(j=0; j<COLS; j++)
  681.         image[i][j] = 0;
  682.  
  683.    j = sizeof(short) * ROWS * COLS;
  684.  
  685.    for(i=0; i<k; i++){
  686.       bytes_written = fwrite(image, 1, j, image_file);
  687.       printf("\n wrote %d bytes", bytes_written);
  688.    }
  689.  
  690.  
  691.    fclose(image_file);
  692.  
  693. }  /* ends create_allocate_tiff_file */
  694.  
  695.  
  696.  
  697.  
  698.  
  699.        /*********************************************
  700.        *
  701.        * write_array_into_tiff_file(...
  702.        *
  703.        * This function takes an array of shorts and 
  704.        * writes them into an existing tiff image file.
  705.        *
  706.        **********************************************/
  707.  
  708. write_array_into_tiff_image(image_file_name, array,
  709.                             il, ie, ll, le)
  710.  
  711.         char    image_file_name[];
  712.         int     il, ie, ll, le;
  713.         short   array[ROWS][COLS];
  714. {
  715.  
  716.    char  buffer[COLS];
  717.    FILE  *image_file;
  718.    int   bytes_written,
  719.          closed,
  720.          i,
  721.           position,
  722.          written;
  723.  
  724.    float a;
  725.  
  726.    long  line_length,
  727.          offset;
  728.  
  729.    struct tiff_header_struct image_header;
  730.  
  731.  
  732.  
  733.    read_tiff_header(image_file_name, &image_header);
  734.  
  735.  
  736.       /***********************************************
  737.       *
  738.       *   Procedure:
  739.       *   Seek to the strip offset where the data begins.
  740.       *   Seek to the first line you want.
  741.       *   Loop over the lines you want to write.
  742.       *      Seek to the first element of the line.
  743.       *      Write the line.
  744.       *      Seek to the end of the data in that line.
  745.       *
  746.       ************************************************/
  747.  
  748.    image_file = fopen(image_file_name, "rb+");
  749.    position   = fseek(image_file,
  750.                       image_header.strip_offset, 
  751.                       SEEK_SET);
  752.    position   = seek_to_first_line(image_file,
  753.                                    &image_header, il);
  754.  
  755.    for(i=0; i<(ll-il); i++){
  756.       offset        = (ie-1)/
  757.                       (8/image_header.bits_per_pixel);
  758.       position      = fseek(image_file, offset, 
  759.                             SEEK_CUR);
  760.       bytes_written = write_line(image_file, array,
  761.                                  i, &image_header, 
  762.                                  ie, le);
  763.       position      = seek_to_end_of_line(image_file,
  764.                                           le, 
  765.                                           &image_header);
  766.       position      = fseek(image_file, 1, SEEK_CUR);
  767.    }  /* ends loop over i  */
  768.  
  769.    closed = fclose(image_file);
  770.  
  771. }  /*  ends write_array_into_tiff_image */
  772.  
  773.  
  774.  
  775.  
  776.        /*********************************************
  777.        *
  778.        *   write_line(...
  779.        *
  780.        *   This function takes an array of shorts, 
  781.        *   extracts the numbers and puts them into 
  782.        *   a buffer, then writes this buffer into a 
  783.        *   tiff file on disk. The process depends on 
  784.        *   the number of bits per pixel used in the 
  785.        *   file (4 or 8).
  786.        *
  787.        **********************************************/
  788.  
  789. write_line(image_file, array, line_number, 
  790.            image_header, ie, le)
  791.    FILE   *image_file;
  792.    int    ie, le, line_number;
  793.    short  array[ROWS][COLS];
  794.    struct tiff_header_struct *image_header;
  795. {
  796.    char     buffer[COLS], first, second;
  797.    float    a, b;
  798.    int      bytes_written, i;
  799.    unsigned int bytes_to_write;
  800.    union    short_char_union scu;
  801.  
  802.    for(i=0; i<COLS; i++)
  803.       buffer[i] = '\0';
  804.  
  805.    bytes_to_write = (le-ie)/
  806.                     (8/image_header->bits_per_pixel);
  807.  
  808.    for(i=0; i<bytes_to_write; i++){
  809.  
  810.         /**********************************************
  811.         *
  812.         *   Use unions defined in cips.h to stuff shorts
  813.         *   into bytess.
  814.         *
  815.         **********************************************/
  816.  
  817.       if(image_header->bits_per_pixel == 8){
  818.        scu.s_num = 0;
  819.        scu.s_num = array[line_number][i];
  820.        buffer[i] = scu.s_alpha[0];
  821.       }  /* ends if bits_per_pixel == 8 */
  822.  
  823.  
  824.       if(image_header->bits_per_pixel == 4){
  825.  
  826.        scu.s_num = 0;
  827.        scu.s_num = array[line_number][i*2];
  828.        first     = scu.s_alpha[0] << 4;
  829.  
  830.        scu.s_num = 0;
  831.        scu.s_num = array[line_number][i*2];
  832.        second    = scu.s_alpha[0] & 0X000F;
  833.  
  834.        buffer[i] = first | second;
  835.       }  /* ends if bits_per_pixel == 4 */
  836.  
  837.    }  /*  ends loop over i  */
  838.  
  839.  
  840.    bytes_written = fwrite(buffer, 1, bytes_to_write, 
  841.                           image_file);
  842.  
  843.    return(bytes_written);
  844.  
  845. }  /* ends write_line  */
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.    /***************************************
  853.    *
  854.    *   insert_short_into_buffer(...
  855.    *
  856.    *   This inserts a two byte short into a
  857.    *   buffer of characters.  It does this
  858.    *   is LSB order.
  859.    *
  860.    ***************************************/
  861.  
  862.  
  863. insert_short_into_buffer(buffer, start, number)
  864.     char  buffer[];
  865.     int   start;
  866.     short number;
  867. {
  868.     union short_char_union lsu;
  869.  
  870.     lsu.s_num       = number;
  871.     buffer[start+0] = lsu.s_alpha[0];
  872.     buffer[start+1] = lsu.s_alpha[1];
  873.  
  874. }  /* ends insert_short_into_buffer */
  875.  
  876.  
  877.  
  878.  
  879.    /***************************************
  880.    *
  881.    *   insert_long_into_buffer(...
  882.    *
  883.    *   This inserts a four byte long into a
  884.    *   buffer of characters.  It does this
  885.    *   is LSB order.
  886.    *
  887.    ***************************************/
  888.  
  889.  
  890.  
  891. insert_long_into_buffer(buffer, start, number)
  892.     char buffer[];
  893.     int  start;
  894.     long number;
  895. {
  896.     union long_char_union lsu;
  897.  
  898.     lsu.l_num       = number;
  899.     buffer[start+0] = lsu.l_alpha[0];
  900.     buffer[start+1] = lsu.l_alpha[1];
  901.     buffer[start+2] = lsu.l_alpha[2];
  902.     buffer[start+3] = lsu.l_alpha[3];
  903.  
  904. }  /* ends insert_short_into_buffer */
  905.  
  906.  
  907.  
  908.  
  909.    /***************************************
  910.    *
  911.    *   round_off_image_size(...
  912.    *
  913.    *   This takes the image header and rounds
  914.    *   it off to a multiple of ROWS and COLS.
  915.    *   e.g. if width=123 it returns 1.
  916.    *
  917.    ***************************************/
  918.  
  919.  
  920. round_off_image_size(image_header, length, width)
  921.     int    *length, *width;
  922.     struct tiff_header_struct *image_header;
  923. {
  924.    *length = (ROWS-10 + image_header->image_length)/ROWS;
  925.    *width  = (COLS-10 + image_header->image_width)/COLS;
  926. } /* ends round_off_image_size */
  927.  
  928.  
  929.  
  930.  
  931.  
  932.    /***********************************************
  933.     *
  934.     *    does_not_exist(...
  935.     *
  936.     *    This function checks the disk to see if
  937.     *    a file exists.  If the file is there this
  938.     *    function returns a 0, if it does not exist
  939.     *    this function returns a 1.
  940.     *
  941.     ***********************************************/
  942.  
  943. does_not_exist(file_name)
  944.     char file_name[];
  945. {
  946.    FILE *image_file;
  947.    int  result;
  948.  
  949.    result = 1;
  950.    image_file = fopen(file_name, "rb");
  951.    if(image_file != NULL){
  952.       result = 0;
  953.       fclose(image_file);
  954.    }
  955.    return(result);
  956. }  /* ends does_not_exist */
  957.  
  958.  
  959.        /*********************************************
  960.        *
  961.        *   file d:\cips\tiff.c
  962.        *
  963.        *   Functions: This file contains
  964.        *     read_tiff_header
  965.        *     extract_long_from_buffer
  966.        *     extract_short_from_buffer
  967.        *
  968.        *   Purpose:
  969.        *     This file contains the subroutines that 
  970.        *     read the tiff files header information.
  971.        *
  972.        *   External Calls:
  973.        *      none
  974.        *
  975.        *   Modifications:
  976.        *      23 June 1990 - created
  977.        *      28 March 1993 - using fopen, fread, fseek
  978.        *          instead of my_open, my_read, lseek.
  979.        *
  980.        ************************************************/
  981.  
  982.  
  983.  
  984.        /***********************************************
  985.        *
  986.        *   read_tiff_header(...
  987.        *
  988.        *   This function reads the header of a TIFF 
  989.        *   file and places the needed information into
  990.        *   the struct tiff_header_struct.
  991.        *
  992.        ***********************************************/
  993.  
  994. read_tiff_header(file_name, image_header)
  995.    char file_name[];
  996.    struct tiff_header_struct *image_header;
  997. {
  998.    char buffer[12], response[80];
  999.  
  1000.    FILE *image_file;
  1001.  
  1002.    int  bytes_read,
  1003.         closed,
  1004.         i,
  1005.         j,
  1006.         lsb,
  1007.         not_finished,
  1008.         position;
  1009.  
  1010.    long bits_per_pixel,
  1011.         image_length,
  1012.         image_width,
  1013.         length_of_field,
  1014.         offset_to_ifd,
  1015.         strip_offset,
  1016.         subfile,
  1017.         value;
  1018.  
  1019.    short entry_count,
  1020.          field_type,
  1021.          s_bits_per_pixel,
  1022.          s_image_length,
  1023.          s_image_width,
  1024.          s_strip_offset,
  1025.          tag_type;
  1026.  
  1027.    image_file = fopen(file_name, "rb");
  1028.    if(image_file != NULL){
  1029.  
  1030.         /*************************************
  1031.         *
  1032.         *   Determine if the file uses MSB
  1033.         *   first or LSB first
  1034.         *
  1035.         *************************************/
  1036.  
  1037.    bytes_read = fread(buffer, 1, 8, image_file);
  1038.  
  1039.    if(buffer[0] == 0x49)
  1040.       lsb = 1;
  1041.    else
  1042.       lsb = 0;
  1043.  
  1044.         /*************************************
  1045.         *
  1046.         *   Read the offset to the IFD
  1047.         *
  1048.         *************************************/
  1049.  
  1050.    extract_long_from_buffer(buffer, lsb, 4, 
  1051.                             &offset_to_ifd);
  1052.  
  1053.    not_finished = 1;
  1054.    while(not_finished){
  1055.  
  1056.         /*************************************
  1057.         *
  1058.         *   Seek to the IFD and read the
  1059.         *   entry_count, i.e. the number of
  1060.         *   entries in the IFD.
  1061.         *
  1062.         *************************************/
  1063.  
  1064.       position   = fseek(image_file, offset_to_ifd, 
  1065.                          SEEK_SET);
  1066.       bytes_read = fread(buffer, 1, 2, image_file);
  1067.       extract_short_from_buffer(buffer, lsb, 0, 
  1068.                                 &entry_count);
  1069.  
  1070.         /***************************************
  1071.         *
  1072.         *   Now loop over the directory entries.
  1073.         *   Look only for the tags we need.  These
  1074.         *   are:
  1075.         *     ImageLength
  1076.         *     ImageWidth
  1077.         *     BitsPerPixel(BitsPerSample)
  1078.         *     StripOffset
  1079.         *
  1080.         *****************************************/
  1081.  
  1082.       for(i=0; i<entry_count; i++){
  1083.        bytes_read = fread(buffer, 1, 12, image_file);
  1084.        extract_short_from_buffer(buffer, lsb, 0, 
  1085.                                  &tag_type);
  1086.  
  1087.        switch(tag_type){
  1088.  
  1089.           case 255: /* Subfile Type */
  1090.              extract_short_from_buffer(buffer, lsb, 2,
  1091.                                        &field_type);
  1092.              extract_short_from_buffer(buffer, lsb, 4,
  1093.                                     &length_of_field);
  1094.              extract_long_from_buffer(buffer, lsb, 8, 
  1095.                                       &subfile);
  1096.              break;
  1097.  
  1098.           case 256: /* ImageWidth */
  1099.              extract_short_from_buffer(buffer, lsb, 2, 
  1100.                                        &field_type);
  1101.              extract_short_from_buffer(buffer, lsb, 4,
  1102.                                     &length_of_field);
  1103.              if(field_type == 3){
  1104.               extract_short_from_buffer(buffer, lsb, 8,
  1105.                                      &s_image_width);
  1106.               image_width = s_image_width;
  1107.              }
  1108.              else
  1109.               extract_long_from_buffer(buffer, lsb, 8, 
  1110.                                        &image_width);
  1111.              break;
  1112.  
  1113.           case 257: /* ImageLength */
  1114.              extract_short_from_buffer(buffer, lsb, 2, 
  1115.                                        &field_type);
  1116.              extract_short_from_buffer(buffer, lsb, 4,
  1117.                                     &length_of_field);
  1118.              if(field_type == 3){
  1119.               extract_short_from_buffer(buffer, lsb, 8,
  1120.                                     &s_image_length);
  1121.               image_length = s_image_length;
  1122.              }
  1123.              else
  1124.               extract_long_from_buffer(buffer, lsb, 8,
  1125.                                        &image_length);
  1126.              break;
  1127.  
  1128.           case 258: /* BitsPerSample */
  1129.              extract_short_from_buffer(buffer, lsb, 2, 
  1130.                                        &field_type);
  1131.              extract_short_from_buffer(buffer, lsb, 4,
  1132.                                     &length_of_field);
  1133.              if(field_type == 3){
  1134.               extract_short_from_buffer(buffer, lsb, 8,
  1135.                                    &s_bits_per_pixel);
  1136.               bits_per_pixel = s_bits_per_pixel;
  1137.              }
  1138.              else
  1139.               extract_long_from_buffer(buffer, lsb, 8,
  1140.                                     &bits_per_pixel);
  1141.              break;
  1142.  
  1143.           case 273: /* StripOffset */
  1144.              extract_short_from_buffer(buffer, lsb, 2, 
  1145.                                        &field_type);
  1146.              extract_short_from_buffer(buffer, lsb, 4,
  1147.                                     &length_of_field);
  1148.              if(field_type == 3){
  1149.               extract_short_from_buffer(buffer, lsb, 8,
  1150.                                     &s_strip_offset);
  1151.               strip_offset = s_strip_offset;
  1152.              }
  1153.              else
  1154.               extract_long_from_buffer(buffer, lsb, 8,
  1155.                                        &strip_offset);
  1156.              break;
  1157.  
  1158.           default:
  1159.              break;
  1160.  
  1161.        }  /* ends switch tag_type */
  1162.  
  1163.       }  /* ends loop over i directory entries */
  1164.  
  1165.       bytes_read = fread(buffer, 1, 4, image_file);
  1166.       extract_long_from_buffer(buffer, lsb, 0, 
  1167.                                &offset_to_ifd);
  1168.       if(offset_to_ifd == 0) not_finished = 0;
  1169.  
  1170.    }  /* ends while not_finished */
  1171.  
  1172.  
  1173.    image_header->lsb                = lsb;
  1174.    image_header->bits_per_pixel = bits_per_pixel;
  1175.    image_header->image_length       = image_length;
  1176.    image_header->image_width        = image_width;
  1177.    image_header->strip_offset       = strip_offset;
  1178.  
  1179.    closed = fclose(image_file);
  1180.    }  /* ends if file opened ok */
  1181.    else{
  1182.       printf("\n\nTIFF.C> ERROR - could not open "
  1183.              "tiff file");
  1184.    }
  1185. }  /* ends read_tiff_header */
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.    /****************************************
  1192.    *
  1193.    *   extract_long_from_buffer(...
  1194.    *
  1195.    *   This takes a four byte long out of a
  1196.    *   buffer of characters.
  1197.    *
  1198.    *   It is important to know the byte order
  1199.    *   LSB or MSB.
  1200.    *
  1201.    ****************************************/
  1202.  
  1203.  
  1204. extract_long_from_buffer(buffer, lsb, start, number)
  1205.    char  buffer[];
  1206.    int       lsb, start;
  1207.    long  *number;
  1208. {
  1209.    int i;
  1210.    union long_char_union lcu;
  1211.  
  1212.    if(lsb == 1){
  1213.       lcu.l_alpha[0] = buffer[start+0];
  1214.       lcu.l_alpha[1] = buffer[start+1];
  1215.       lcu.l_alpha[2] = buffer[start+2];
  1216.       lcu.l_alpha[3] = buffer[start+3];
  1217.    }  /* ends if lsb = 1 */
  1218.  
  1219.    if(lsb == 0){
  1220.       lcu.l_alpha[0] = buffer[start+3];
  1221.       lcu.l_alpha[1] = buffer[start+2];
  1222.       lcu.l_alpha[2] = buffer[start+1];
  1223.       lcu.l_alpha[3] = buffer[start+0];
  1224.    }  /* ends if lsb = 0      */
  1225.  
  1226.    *number = lcu.l_num;
  1227.  
  1228.  
  1229. }  /* ends extract_long_from_buffer */
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.    /****************************************
  1236.    *
  1237.    *   extract_short_from_buffer(...
  1238.    *
  1239.    *   This takes a two byte short out of a
  1240.    *   buffer of characters.
  1241.    *
  1242.    *   It is important to know the byte order
  1243.    *   LSB or MSB.
  1244.    *
  1245.    ****************************************/
  1246.  
  1247.  
  1248.  
  1249. extract_short_from_buffer(buffer, lsb, start, number)
  1250.    char  buffer[];
  1251.    int       lsb, start;
  1252.    short *number;
  1253. {
  1254.  
  1255.    int i;
  1256.    union short_char_union lcu;
  1257.  
  1258.    if(lsb == 1){
  1259.       lcu.s_alpha[0] = buffer[start+0];
  1260.       lcu.s_alpha[1] = buffer[start+1];
  1261.    }  /* ends if lsb = 1 */
  1262.  
  1263.    if(lsb == 0){
  1264.       lcu.s_alpha[0] = buffer[start+1];
  1265.       lcu.s_alpha[1] = buffer[start+0];
  1266.    }  /* ends if lsb = 0      */
  1267.  
  1268.    *number = lcu.s_num;
  1269.  
  1270.  
  1271. }  /* ends extract_short_from_buffer */
  1272.